package org.moca.activity;

import java.util.HashMap;

import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.moca.R;
import org.moca.db.MocaDB.ProcedureSQLFormat;
import org.moca.db.MocaDB.SavedProcedureSQLFormat;
import org.moca.service.QueueManager;

import android.app.ListActivity;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;

public class SavedProcedureList extends ListActivity implements SimpleCursorAdapter.ViewBinder {
	private static final String TAG = SavedProcedureList.class.toString();
	private static final String[] PROJECTION = {SavedProcedureSQLFormat._ID,
												SavedProcedureSQLFormat.GUID, 
												SavedProcedureSQLFormat.PROCEDURE_ID, 
												SavedProcedureSQLFormat.PROCEDURE_STATE, 
												SavedProcedureSQLFormat.UPLOAD_STATUS,
												SavedProcedureSQLFormat.UPLOAD_QUEUE };
	private HashMap<Integer, String> procedureToName = new HashMap<Integer, String>();
	
	/**
	 * Lookup procedure name in the database by primary key with memoization.
	 * @return the procedure name for procedureId 
	 */
	private String lookupProcedureName(int procedureId) {
		
		if(procedureToName.containsKey(procedureId)) {
			return procedureToName.get(procedureId);
		}
		Cursor cur2 = getContentResolver().query(ProcedureSQLFormat.CONTENT_URI,
				new String[] { ProcedureSQLFormat.TITLE },
				ProcedureSQLFormat._ID + " = ?",
				new String[] { Integer.toString(procedureId) }, null);
		cur2.moveToFirst();
		String title = cur2.getString(0);
		cur2.deactivate();
		
		procedureToName.put(procedureId, title);
		
		return title;
	}
	
	private String getPatientNameFromData(String jsonData) {
        String patientId = "";
        String patientFirst = "";
        String patientLast = "";
        
        try {
    		JSONTokener tokener = new JSONTokener(jsonData);
            JSONObject answersDict = new JSONObject(tokener);
            if (answersDict.has("patientId"))
            	patientId = (String)answersDict.get("patientId");
            if (answersDict.has("newPatientFirstName"))
            	patientFirst = (String)answersDict.get("newPatientFirstName");
            if (answersDict.has("patientFirstName") && "".equals(patientFirst))
            	patientFirst = (String)answersDict.get("patientFirstName");
            if (answersDict.has("newPatientLastName"))
            	patientLast = (String)answersDict.get("newPatientLastName");
            if (answersDict.has("patientLastName") && "".equals(patientLast))
            	patientLast = (String)answersDict.get("patientLastName");
        } catch(JSONException e) {
        	
        }
        
        StringBuilder result = new StringBuilder(patientId);
        if(!patientFirst.equals("")) {
        	result.append(" - ");
        	result.append(patientFirst);
        	result.append(" ");
        	result.append(patientLast);
        }
        return result.toString();
	}
	
	private String getUploadStatus(int queueStatus, int queuePosition) {
		String message = "";
		if (queueStatus == 0 || queueStatus == -1) message = "Not Uploaded";
		else if (queueStatus == QueueManager.UPLOAD_STATUS_WAITING) {
			message = "Waiting in the queue to be uploaded, " + queuePosition;
			if (queuePosition == -1) message = "Waiting in the queue to be uploaded";
			else if (queuePosition == 1) message += "st in line";
			else if (queuePosition == 2) message += "nd in line";
			else if (queuePosition == 3) message += "rd in line";
			else message += "th in line";
		}
		else if (queueStatus == QueueManager.UPLOAD_STATUS_SUCCESS) message = "Uploaded Successfully";
		else if (queueStatus == QueueManager.UPLOAD_STATUS_IN_PROGRESS) message = "Upload in progress";
		else if (queueStatus == QueueManager.UPLOAD_NO_CONNECTIVITY) message = "Upload stalled - Waiting for connectivity";
		else if (queueStatus == QueueManager.UPLOAD_STATUS_FAILURE) message = "Upload failed";
		else if (queueStatus == QueueManager.UPLOAD_STATUS_CREDENTIALS_INVALID) message = "Upload stalled - username/password incorrect";
		else Log.i(TAG, "Not a valid number stored in database.");
		Log.i(TAG, "Message being set as the status of the procedure: " + message);
		return message;
	}
	
	
	public boolean setViewValue(View v, Cursor cur, int columnIndex) {
		try {
			if (v instanceof TextView) {
				((TextView)v).setText(cur.getString(columnIndex));
				switch(columnIndex) {
				case 2:
					//Log.i(TAG, "Setting procedure name in SavedProcedureList text");
					int procedureId = cur.getInt(columnIndex);
					String procedureName = lookupProcedureName(procedureId);
					((TextView)v).setText(procedureName);
					break;
				case 3:
					//Log.i(TAG, "Setting patient id and name in SavedProcedureList text");
					String jsonData = cur.getString(columnIndex);
					String patientName = getPatientNameFromData(jsonData);
					((TextView)v).setText(patientName);
					break;
				case 4:
					Log.i(TAG, "Setting upload queue status in text view.");
					int queueStatus = cur.getInt(columnIndex);
					int queuePosition = cur.getInt(5);
					String message = getUploadStatus(queueStatus, queuePosition + 1);
					((TextView)v).setText(message);
					break;
				}
			}
		}
		catch (Exception e) {
			Log.e(TAG, "Exception in setting the text in the list: " + e.toString());
		}
		
		
		
		return true;
	}
		
	@Override
	public void onCreate(Bundle bundle) {
		
		super.onCreate(bundle);
		setContentView(R.layout.info);
		
		//super.onCreate(bundle);
		//super.onCreate(savedInstanceState);
        
        /*
        Cursor cursor = managedQuery(SavedProcedureSQLFormat.CONTENT_URI, PROJECTION, null,
                null, SavedProcedureSQLFormat.DEFAULT_SORT_ORDER);

        try {
	        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,	                
	        		R.layout.row, cursor,
	                new String[] { SavedProcedureSQLFormat.PROCEDURE_ID, SavedProcedureSQLFormat.PROCEDURE_STATE, 
	        															SavedProcedureSQLFormat.UPLOAD_STATUS },
	                new int[] { R.id.toptext, R.id.bottomtext, R.id.queue_status });
	        adapter.setViewBinder(this);
	        setListAdapter(adapter);
        }
        catch (Exception e) {
			Log.e(TAG, "Exception in creating SimpleCursorAdapter: " + e.toString());
		}
		*/
	}
	
	@Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);
        Log.i(TAG, "procedure Uri in onListItemClick: " + uri);
        String action = getIntent().getAction();
        if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {
            // The caller is waiting for us to return a note selected by
            // the user.  The have clicked on one, so return it now.
            setResult(RESULT_OK, new Intent().setData(uri));
            finish();
        } else {
            // Launch activity to view/edit the currently selected item
            startActivity(new Intent(Intent.ACTION_EDIT, uri));
        }
    }
	
	public static final int SELECT_ALL = 0;
	public static final int DELETE = 1;
	//public static final int RESEND = 2;
	//public static final int CANCEL_UPLOAD = 2;

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		menu.add(0, SELECT_ALL, 0, "Select All");
		menu.add(0, DELETE, 1, "Delete");
		//menu.add(0, RESEND, 2, "Resend");
		//menu.add(0, CANCEL_UPLOAD, 2, "Cancel Upload");
		return true;
	}
	
	public boolean onOptionsItemSelected(MenuItem item){

		switch (item.getItemId()) {
		case SELECT_ALL:
			selectAllProcedures();
			return true;
		case DELETE:
			deleteSelected();
			return true;
		/*case RESEND:
			resendSelected();
			return true;
		case CANCEL_UPLOAD:
			cancelUploads();
			return true;*/
		}
		return false;
	}
	
	private Context mContext = this;
	//All checkboxes will be checked
	private void selectAllProcedures() {
		try{
			for (int x = 0; x < getListAdapter().getCount(); x++) {
				CheckBox checkbox = (CheckBox) getListView().getChildAt(x).findViewById(R.id.icon);
				checkbox.setChecked(true);
				Log.i(TAG, "Is checkbox checked? (Should be true): " + checkbox.isChecked());
			}
		}
		catch (Exception e) {
			Log.i(TAG, "Exception in selectAll(): " + e.toString());
		}
	}
	
	//All checkboxes will be unchecked
	//To be used after one of these actions is performed
	private void unselectAllProcedures() {
		try{
			for (int x = 0; x < getListAdapter().getCount(); x++) {
				CheckBox checkbox = (CheckBox) getListView().getChildAt(x).findViewById(R.id.icon);
				checkbox.setChecked(false);
				Log.i(TAG, "Is checkbox checked? (Should be false): " + checkbox.isChecked());
			}
		}
		catch (Exception e) {
			Log.i(TAG, "Exception in unselectAll(): " + e.toString());
		}
	}
	
	// Get Uri for each procedure that is checked and delete it
	private void deleteSelected() {
		try{
			for (int x = 0; x < getListAdapter().getCount(); x++) {
				CheckBox checkbox = (CheckBox) getListView().getChildAt(x).findViewById(R.id.icon);
				Uri procedure = ContentUris.withAppendedId(getIntent().getData(), (Long) getListView().getItemIdAtPosition(x));
				Log.i(TAG, "Is checkbox checked? (if yes then should be deleted) " + checkbox.isChecked());
				if (checkbox.isChecked()) {
					Log.i(TAG, "Deleting procedure with Uri: " + procedure);
					mContext.getContentResolver().delete(procedure, null, null);
				}
			}
			unselectAllProcedures();
		}
		catch (Exception e) {
			unselectAllProcedures();
			Log.i(TAG, "Exception in deleteSelected(): " + e.toString());
		}
	}
	
	//private static ContentResolver contentResolver;
	//If selected procedures are in queue or are currently being uploaded, cancel the upload
	/*private void cancelUploads() {
		try{
			for (int x = 0; x < getListAdapter().getCount(); x++) {
				CheckBox checkbox = (CheckBox) getListView().getChildAt(x).findViewById(R.id.icon);
				Uri procedure = ContentUris.withAppendedId(getIntent().getData(), (Long) getListView().getItemIdAtPosition(x));
				if (checkbox.isChecked()) {
					// TODO Make is cancel if its in the middle of uploading, not just taking it out of the queue
					BackgroundUploader.removeFromQueue(procedure);
				}
			}
			unselectAllProcedures();
		}
		catch (Exception e) {
			unselectAllProcedures();
			Log.i(TAG, "Exception in cancelSelected(): " + e.toString());
		}
	}*/
}
